ECMAScript 2015
ECMAScript 2015 (ES6)
1. 개요
ECMAScript 2015(이하 ES6)는 Ecma International에서 정의한 JavaScript 언어의 표준 사양으로, 2009년 출시된 ES5 이후 약 6년 만에 발표된 가장 거대한 규모의 업데이트 버전입니다.
ES6는 단순한 문법 추가를 넘어, JavaScript를 단순한 스크립트 언어에서 대규모 애플리케이션 개발이 가능한 현대적인 프로그래밍 언어로 진화시킨 상징적 전환점으로 평가받습니다. 이전 버전인 ES5가 기존 기능의 보완에 집중했다면, ES6는 모듈화, 클래스 기반 객체 지향, 효율적인 비동기 처리 등 현대적 소프트웨어 공학의 패러다임을 수용하는 방향으로 변화하였습니다.
ES5 vs ES6 주요 차이점 비교
| 구분 | ES5 (ECMAScript 5) | ES6 (ECMAScript 2015) |
|---|---|---|
| 변수 선언 | var (함수 레벨 스코프) |
let, const (블록 레벨 스코프) |
| 함수 정의 | function 키워드 중심 |
화살표 함수(Arrow Function) 도입 |
| 객체 지향 | 프로토타입 기반 상속 | class 문법 도입 (Syntactic Sugar) |
| 문자열 처리 | 문자열 연결(+) 사용 |
템플릿 리터럴(Template Literals) 도입 |
| 비동기 처리 | 콜백(Callback) 함수 중심 | <a href="/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC/Promise" class="wiki-link wiki-link-missing">Promise</a> 객체 도입 |
| 모듈 시스템 | 표준 모듈 시스템 부재 (CommonJS 등 사용) | import, export 표준 모듈 도입 |
2. 주요 문법 변화 (기초)
2.1 변수 선언 방식의 변화
ES6에서는 기존 var의 문제점인 호이스팅(Hoisting, 변수 선언문이 최상단으로 끌어올려지는 현상)과 함수 레벨 스코프의 모호함을 해결하기 위해 두 가지 새로운 키워드를 도입했습니다.
let: 재할당이 가능한 블록 레벨 스코프 변수입니다.const: 재할당이 불가능한 상수(Constant)를 선언할 때 사용합니다.
특히 let과 const는 호이스팅이 발생하지만, 선언 단계와 초기화 단계가 분리되어 있습니다. 선언 전 변수에 접근하려고 하면 TDZ(Temporal Dead Zone, 일시적 사각지대)에 의해 ReferenceError가 발생하며, 이를 통해 잠재적인 런타임 에러를 방지하고 코드의 예측 가능성을 높였습니다.
2.2 화살표 함수 (Arrow Functions)
함수 선언식을 간결하게 표현할 수 있는 문법으로, function 키워드를 생략하고 => 기호를 사용합니다. 특히 화살표 함수는 자신만의 this 바인딩을 가지지 않고 상위 스코프의 this를 그대로 사용하는 렉시컬 this(Lexical this) 특성을 가집니다.
// ES5 방식
var add = function(a, b) {
return a + b;
};
// ES6 화살표 함수 방식
const add = (a, b) => a + b;
2.3 템플릿 리터럴 (Template Literals)
백틱(`)을 사용하여 문자열을 정의하며, ${} 문법을 통해 문자열 내부에 변수나 표현식을 직접 삽입할 수 있습니다. 또한 줄바꿈을 그대로 인식하여 다중행 문자열 작성이 용이합니다.
const name = "Alice";
const greeting = `Hello, ${name}!
Welcome to ES6 world.`;
3. 데이터 구조 및 객체 지향 확장 (심화)
3.1 Class 문법
ES6는 class 키워드를 도입하여 객체 지향 프로그래밍(OOP) 스타일의 코드를 작성할 수 있게 했습니다. 이는 내부적으로는 여전히 프로토타입 기반으로 동작하지만, 개발자에게는 더 친숙한 클래스 기반 문법을 제공하는 '문법적 설탕(Syntactic Sugar)'입니다.
상속을 구현할 때는 extends 키워드를 사용하며, 자식 클래스의 constructor 내에서는 반드시 super()를 호출해야 합니다. super()를 호출하지 않으면 this를 사용할 수 없어 에러가 발생합니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 부모 클래스의 constructor 호출 필수
this.breed = breed;
}
speak() {
console.log(`${this.name} barks!`);
}
}
3.2 Map과 Set
기존의 Object와 Array가 가진 한계를 극복하기 위해 새로운 컬렉션 타입이 추가되었습니다.
| 구분 | 기존 방식 (Object/Array) | 신규 방식 (Map/Set) | 주요 특징 |
|---|---|---|---|
| Key-Value | Object (키가 문자열/심볼로 제한) |
Map (어떤 값도 키가 될 수 있음) |
순서 보장, 크기(size) 확인 용이 |
| Unique Value | Array (중복 값 허용) |
Set (중복 값 자동 제거) |
고유한 값들의 집합 관리 |
3.3 심볼 (Symbol)
ES6에서는 7번째 기본 자료형인 Symbol이 도입되었습니다. 심볼은 Symbol() 함수를 통해 생성하며, 생성될 때마다 매번 유일무이한 값을 가집니다. 주로 객체의 프로퍼티 키로 사용하여, 외부에서 접근하기 어렵게 만들거나 다른 프로퍼티와의 이름 충돌을 방지하는 용도로 사용됩니다.
4. 제너레이터와 이터레이터
4.1 이터레이터 (Iterator)
이터레이터는 컬렉션의 요소들을 순차적으로 탐색할 수 있게 해주는 객체입니다. next() 메서드를 호출하면 { value: 값, done: 불리언 } 형태의 객체를 반환하며, 이를 통해 for...of 루프와 같은 반복문이 작동합니다.
4.2 제너레이터 (Generator)
제너레이터는 함수의 실행을 중간에 멈췄다가 나중에 다시 재개할 수 있는 특수한 함수입니다. function* 키워드로 정의하며, yield 키워드를 사용하여 값을 반환하고 실행을 일시 정지합니다.
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
5. 비동기 처리와 최신 기능
5.1 Promise
Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 기존의 '콜백 지옥(Callback Hell)' 문제를 해결하고 비동기 흐름을 체이닝(then, catch) 형태로 관리할 수 있게 합니다.
- Pending: 초기 상태, 완료 또는 실패하지 않은 상태
- Fulfilled: 비동기 처리가 성공적으로 완료된 상태
- Rejected: 비동기 처리가 실패한 상태
const fetchData = () => {
return new Promise((resolve, reject) => {
const success = true;
setTimeout(() => {
success ? resolve("데이터 로드 성공!") : reject("에러 발생!");
}, 1000);
});
};
fetchData()
.then(result => console.log(result)) // 성공 시 실행
.catch(error => console.error(error)) // 실패 시 실행
.finally(() => console.log("작업 종료")); // 무조건 실행
5.2 구조 분해 할당 및 스프레드 연산자
데이터 핸들링의 효율성을 극대화하는 문법들이 도입되었습니다.
- 구조 분해 할당(Destructuring): 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있습니다. 객체 구조 분해 시에는
:를 사용하여 변수명을 변경(Aliasing)할 수 있습니다. - 스프레드 연산자(Spread Operator):
...기호를 사용하여 배열이나 객체의 내용을 펼쳐서 복사하거나 합칠 수 있습니다. - 나머지 매개변수(Rest Parameters): 함수 정의 시
...를 사용하여 정해지지 않은 수의 인자를 배열로 받을 수 있습니다.
// 1. 구조 분해 할당 및 변수명 변경
const user = { name: 'Kim', age: 25 };
const { name, age: userAge } = user; // age를 userAge라는 이름으로 할당
console.log(name, userAge); // "Kim", 25
const colors = ['red', 'green', 'blue'];
const [first, second] = colors; // first: 'red', second: 'green'
// 2. 스프레드 연산자
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]
// 3. 나머지 매개변수
function sum(...args) {
return args.reduce((acc, cur) => acc + cur, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
6. 모듈 시스템 및 기타 변경 사항
6.1 표준 모듈 시스템 (import / export)
ES6 이전에는 CommonJS(Node.js)나 AMD와 같은 비표준 모듈 시스템을 사용했으나, ES6부터는 언어 차원의 표준 모듈 시스템이 도입되었습니다.
export: 모듈 내부의 변수, 함수, 클래스를 외부로 공개합니다.import: 외부 모듈에서 공개된 기능을 가져와 사용합니다.
6.2 기본 매개변수 (Default Parameters)
함수 호출 시 인자가 전달되지 않았을 때 사용할 기본값을 설정할 수 있습니다.
const greet = (name = "Guest") => `Hello, ${name}!`;
console.log(greet()); // "Hello, Guest!"
7. 호환성 및 트랜스파일링
7.1 브라우저 지원 현황
ES6는 현대적인 브라우저에서는 대부분 지원되지만, Internet Explorer(IE)와 같은 구형 브라우저에서는 작동하지 않습니다.
| 브라우저 | 지원 여부 | 비고 |
|---|---|---|
| Chrome | ✓ | 매우 높음 |
| Firefox | ✓ | 매우 높음 |
| Safari | ✓ | 높음 |
| Edge | ✓ | 높음 |
| IE 11 | ✗ | 대부분의 ES6 문법 미지원 |
7.2 바벨(Babel)과 폴리필(Polyfill)
구형 브라우저에서도 ES6 코드를 실행하기 위해 두 가지 기법이 사용됩니다.
- 트랜스파일러 (Transpiler): Babel과 같은 도구를 사용하여 최신 버전의 JavaScript 코드를 구형 브라우저가 이해할 수 있는 하위 버전(주로 ES5)의 문법으로 변환하는 과정입니다. 예를 들어,
const나let을var로, 화살표 함수를 일반 함수식으로 변환하여 호환성을 확보합니다. - 폴리필 (Polyfill): 문법 변환만으로 해결되지 않는 새로운 API(예:
Promise,Map,Array.from)를 구형 브라우저가 이해할 수 있도록 직접 구현한 코드를 추가하는 방식입니다.
이 문서는 AI 모델(gemma-4-31b)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.